#pragma once 

#include <mutex>
#include <string>
using namespace std;

#include "topdbs_common.hpp"
#include "topdbs_base_connection.hpp"

namespace topdbs
{
	class TOPDBS_API SQLConnection
	{
	public:	
		SQLConnection();
		virtual ~SQLConnection();

		SQLConnection(const SQLConnection&) = delete;
		SQLConnection& operator=(const SQLConnection&) = delete;
		SQLConnection(SQLConnection &&) = default;
		SQLConnection& operator=(SQLConnection &&) = default;

		eDBSClient_t getDbsCient();
		std::string  getDbsVersion();
		std::string  getErrors();
		std::string  getSqlcode();
		std::string  getSqlerr();	
		
		topdbs_base_connection* getConnection();
		void setClientEncode(const string& encode);
		void setLocktime(uint16_t locktime);
		void setEncrypt(bool on);
		uint64_t getConnectionID() const;

		/// @brief 
		/// @param dbsClient 
		/// @param dbString host:port@dbName
		/// @param user 
		/// @param pass 
		/// @param pOption 
		/// @return 
		int  connect(eDBSClient_t dbsClient,const string& dbString,const string& user=string(),const string& pass=string(),void* pOption = NULL );
		int  connect(const string& dbsfile,const string& dbsgroup=string());

		bool isConnected();
		int  reConnect();
		int  disConnect();	
		int  autoCommit(bool on = true);
		int  begin();
		int  commit();
		int  rollback();
		bool isTransaction();	
	private:
		topdbs_base_connection* m_pConnection;   
		eDBSClient_t m_dbsClient;
		string m_dbsCharset;
		uint16_t m_dbsLocktime;
		uint64_t m_dbsConnectionId;
		bool m_dbsEncrypt;
	private:
		/// @brief static variable
		static std::mutex  m_lock; 
		static SQLConnection* m_instance;
		static bool m_status;
		class AutoRelease {
			public:
			~AutoRelease() {
				UnIntEnv();
			};
		};	
		static AutoRelease m_release;  	

	public:	
		/// @brief static function 
		static int InitEnv(
			eDBSClient_t dbsClient,
			const string& dbString,
			const string& user = string(),
			const string& pass = string(),
			const string& charset = string(),
			bool encrypt = false,
			void* pOption = NULL);
		static int InitEnv(const DBSConnectionParams& dbsParams);
		static int InitEnv(const string& dbsfile,const string& dbsgroup = string());
		static int UnIntEnv();
		static SQLConnection* GetInstance();
		static SQLConnection* GetConnection();
	};
}
